﻿#include <QModbusDevice>
#include "formmodbus.h"
#include "ui_formmodbus.h"
#include "commconfig.h"
#include "widgetutils.h"

FormModbus::FormModbus(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FormModbus)
{
    ui->setupUi(this);

    ui->writeTable->addItem(tr("Coils"));
    ui->writeTable->addItem(tr("Discrete Inputs"));
    ui->writeTable->addItem(tr("Input Registers"));
    ui->writeTable->addItem(tr("Holding Registers"));

    writeModel = new WriteRegisterModel(this);
    writeModel->setStartAddress(ui->writeAddress->value());
    writeModel->setNumberOfValues(ui->writeSize->currentText());
    ui->writeValueTable->setModel(writeModel);
    ui->writeValueTable->hideColumn(2);
    connect(writeModel, &WriteRegisterModel::updateViewport, ui->writeValueTable->viewport(),
        static_cast<void (QWidget::*)()>(&QWidget::update));

}

FormModbus::~FormModbus()
{
    delete ui;
}

void FormModbus::setComm(BaseModbus *modbus)
{
    m_modbus=modbus;
    QWidget *w=modbus->getConfigWidget();
    setCfgWidget(w);
    loadUiCfg();
}

void FormModbus::setCfgWidget(QWidget *w)
{
    QVBoxLayout *vbox = new QVBoxLayout();
    vbox->addWidget(w);
    ui->groupBox->setLayout(vbox);
}

void FormModbus::loadUiCfg()
{
//    QString gn=QString("%1_ui").arg(_req->name());
//    RequestCfg cfg=AppConfig::instance().getReqCfg(gn);
}

void FormModbus::on_readButton_clicked()
{
    WidgetUtils::Execute(ui->readButton,[this]{
        int addr=ui->readAddress->value();
        int count=ui->readSize->currentText().toInt();
        QStringList items=readData(ui->writeTable->currentText(),addr,count);
        ui->readValue->clear();
        ui->readValue->addItems(items);
    });
}

QStringList FormModbus::readData(QString dataType,int addr,int count)
{
//    ui->writeTable->addItem(tr("Coils"));
//    ui->writeTable->addItem(tr("Discrete Inputs"));
//    ui->writeTable->addItem(tr("Input Registers"));
//    ui->writeTable->addItem(tr("Holding Registers"));
    QStringList ret;
    if(dataType=="Coils")
    {
        QList<bool> data=m_modbus->readBits(addr,count);
        for(int i=0;i<data.count();i++)
        {
            ret.append(QString("Address:%1, Value:%2").arg(i+addr).arg(data.at(i)));
        }
    }
    else if(dataType=="Discrete Inputs")
    {
        QList<bool> data=m_modbus->readInputBits(addr,count);
        for(int i=0;i<data.count();i++)
        {
            ret.append(QString("Address:%1, Value:%2").arg(i+addr).arg(data.at(i)));
        }
    }
    else if(dataType=="Input Registers")
    {
        QList<uint16_t> data=m_modbus->readInputRegisters(addr,count);
        for(int i=0;i<data.count();i++)
        {
            ret.append(QString("Address:%1, Value:%2").arg(i+addr).arg(data.at(i)));
        }
    }
    else if(dataType=="Holding Registers")
    {
        QList<uint16_t> data=m_modbus->readRegisters(addr,count);
        for(int i=0;i<data.count();i++)
        {
            ret.append(QString("Address:%1, Value:%2").arg(i+addr).arg(data.at(i)));
        }
    }
    return ret;
}

void FormModbus::on_writeButton_clicked()
{
    WidgetUtils::Execute(ui->readButton,[this]{
        QString dataType=ui->writeTable->currentText();
        if(dataType=="Coils")
        {
            QList<bool> coils;
            int addr=ui->writeAddress->value();
            for (int i = 0; i < writeModel->rowCount(); i++) {
                coils.append(writeModel->m_coils[i]);
            }
            m_modbus->writeBits(addr,coils.count(),coils);
        }
        else if(dataType=="Holding Registers")
        {
            QList<quint16> registers;
            int addr=ui->writeAddress->value();
            for (int i = 0; i < writeModel->rowCount(); i++) {
                registers.append(writeModel->m_holdingRegisters[i]);
            }
            m_modbus->writeRegisters(addr,registers.count(),registers);
        }
    });
}

void FormModbus::on_writeTable_currentIndexChanged(int index)
{
    const bool coilsOrHolding = index == 0 || index == 3;
    if (coilsOrHolding) {
        ui->writeValueTable->setColumnHidden(1, index != 0);
        ui->writeValueTable->setColumnHidden(2, index != 3);
        ui->writeValueTable->resizeColumnToContents(0);
    }

    ui->writeButton->setEnabled(coilsOrHolding);
    ui->writeGroupBox->setEnabled(coilsOrHolding);
}
